package com.example.netty.linebase.server;

import com.example.netty.common.server.ConnectionCountHandler;
import com.example.netty.common.server.ServerHeartBeatServerHandler;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.LineBasedFrameDecoder;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;
import io.netty.handler.timeout.IdleStateHandler;

import java.util.concurrent.TimeUnit;

/**
 * <p></p>
 *
 * @author xin
 * @version 2023/11/2 16:04
 **/
@SuppressWarnings("all")
public class LineBaseServerInitializer extends ChannelInitializer<SocketChannel> {
    private static final String ENCODER = "encoder";
    private static final String DECODER = "decoder";

    /**
     * 如果failFast=true，当超过maxLength后会立刻抛出TooLongFrameException，不再进行解码；
     * 如果failFast=false，那么会等到解码出一个完整的消息后才会抛出TooLongFrameException
     */
    private final boolean failFast = false;
    /**
     * 为读超时时间（即多长时间没有接受到客户端发送数据）
     */
    private final long readerIdleTime = 0;
    /**
     * 为写超时时间（即多长时间没有向客户端发送数据）
     */
    private final long writerIdleTime = 0;
    /**
     * 所有类型（读或写）的超时时间
     */
    private final long allIdleTime = 0;

    @Override
    protected void initChannel(SocketChannel ch) throws Exception {
        ch.pipeline().addLast(new IdleStateHandler(readerIdleTime, writerIdleTime, allIdleTime, TimeUnit.SECONDS))
                // 优先判断最大长度
                // stripDelimiter:解码后的消息是否去除分隔符,此处是 通过 \n\r来进行区分，因此接收到消息后需要去掉分割符
                // failFast = false, 那么会等到解码出完整消息才会抛出 TooLongException。
                .addLast(new LineBasedFrameDecoder(Integer.MAX_VALUE, true, failFast))
                .addLast(ENCODER, new StringEncoder())
                .addLast(DECODER, new StringDecoder())
                .addLast(new ConnectionCountHandler())
                .addLast(new LineBaseServerHandler())
                .addLast(new ServerHeartBeatServerHandler())

        ;

    }
}
